package com.gitee.huanminabc.fastboot.web.stage;

import com.gitee.huanminabc.jcommon.base.UrlUtil;
import com.gitee.huanminabc.jcommon.reflect.AnnotationUtil;
import com.gitee.huanminabc.jcommon.reflect.ReflectPath;
import com.gitee.huanminabc.fastboot.load.stage.poststage.AppLoadPostStage;
import com.gitee.huanminabc.fastboot.context.AppContext;
import com.gitee.huanminabc.fastboot.web.annotation.http.*;
import com.gitee.huanminabc.fastboot.web.context.AppWebContext;
import com.gitee.huanminabc.fastboot.web.servlet.InterfaceMethodDefDesc;
import com.gitee.huanminabc.fastboot.web.servlet.RequestMethodEnum;
import com.gitee.huanminabc.nullchain.common.NullResult;
import lombok.extern.slf4j.Slf4j;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
 * @program: netty-web
 * @description:
 * @author: huanmin
 * @create: 2025-04-01 11:07
 **/
@Slf4j
public class ControllerInterfaceHandlerStage implements AppLoadPostStage {
    @Override
    public void run() {
        AppContext.allControllerClasses.stream().parallel().forEach(value -> {
            RequestMapping annotation = AnnotationUtil.getClassAnnotation(value, RequestMapping.class);
            if (annotation == null) {
                return;
            }
            //获取类的url
            String classUrl = annotation.value();
            //获取类的所有方法
            Method[] methods = value.getDeclaredMethods();
            for (Method method : methods) {
                //获取方法上的@RequestMapping
                Annotation methodAnnotation = AnnotationUtil.getMethodAnnotation(method, DeleteMapping.class, GetMapping.class, PostMapping.class, PutMapping.class);
                if (methodAnnotation == null) {
                    continue;
                }
                String methodUrl = AnnotationUtil.getAnnotationPropertyValue(methodAnnotation, "value");
                //获取请求的协议 , 注解的名称去掉Mapping
                String protocol = methodAnnotation.annotationType().getSimpleName().replace("Mapping", "").toUpperCase();
                String urlFull = UrlUtil.mergeUrl(AppWebContext.appServletConfig.getPrefix(),classUrl, methodUrl);
                //创建对象
                InterfaceMethodDefDesc interfaceMethodDefDesc = new InterfaceMethodDefDesc(
                        AppContext.containerClassAll.get(value),
                        method,
                        urlFull,
                        RequestMethodEnum.getEnum(protocol)
                );
                //接口的返回值类型校验必须是NullResult
                if (!NullResult.class.isAssignableFrom(method.getReturnType())) {
                    log.error("接口方法{}的返回值类型必须是NullResult", ReflectPath.getMethodParamAll(interfaceMethodDefDesc.getMethod()));
                    System.exit(1);
                }
                AppWebContext.httpInterfaceMethodDescMap.put(urlFull, interfaceMethodDefDesc);
            }
        });
        log.debug("ControllerInterfaceHandlerStage: [{}]  load success", AppWebContext.httpInterfaceMethodDescMap.size());
    }
}
